﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Kiosk.Library;
using System.Windows.Threading;
using System.Configuration;
using System.IO;
using Kiosk.Utilities;
using Kiosk.Animation;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Threading;


namespace Kiosk.UserControls
{

    /// <summary>
    /// Interaction logic for PresentationPresenter.xaml
    /// </summary>
    public partial class PresentationPresenter : System.Windows.Controls.UserControl
    {
        private DispatcherTimer timer =  new DispatcherTimer();
        private PresentationReadOnlyList presList;
        private SlideReadOnlyList slides;
        private PresentationInfo currentPresentation = null;
        private SlideInfo currentSlide = null;
        string tempFile;
        string slidePath;
        private HtmlImageGenerator imgGen;
        int currSlideNum = 0;

        public PresentationPresenter()
        {
            InitializeComponent();

            timer.Interval = TimeSpan.FromSeconds(45);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();

            // location we store the merged template and slide data
            slidePath = ConfigurationManager.AppSettings["SlideLocation"];
            tempFile = slidePath + "temp.html";

            // setup our image generator
            imgGen = new HtmlImageGenerator()
            {
                SourceUri = new Uri(tempFile),
                Height = 600,
                Width = 800
            };
            imgGen.GenerationComplete += new GenerationCompleteEventHandler(imgGen_GenerationComplete);
            try
            {

                presList = PresentationReadOnlyList.GetAllEnabledPresentations();
                GetNextPresentation();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error in presentation loading");
            }

        }
        
        /// <summary>
        /// Gets the next presentation, sets it to the current presentation, and loads up it's slides, displays the first slide
        /// </summary>
        private void GetNextPresentation()
        {
            if(presList.Count > 0)
            {
                currentPresentation = presList.GetNextPresentation();
                if (currentPresentation != null)
                {
                    slides = SlideReadOnlyList.GetSlidesByPresentationID(currentPresentation.PresentationID);
                    if (slides.Count > 0)
                    {
                        currentSlide = slides.GetNextSlide();
                        ChangeSlide();
                    }
                }
                else
                {
                    slides = null;
                }


            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            // try to get the next slide, if we get one, display it and return immediately
            if (slides != null && slides.Count > 0)
            {
                currentSlide = slides.GetNextSlide();
                if (currentSlide != null)
                {
                    ChangeSlide();
                    return;
                }
            }

            // we don't have any slides, get the next presentation
            if (currentSlide == null)
            {
                GetNextPresentation();
            }
            // we don't have a presentation or went through all of them, try to refresh the list
            if (currentPresentation == null)
            {
                presList = PresentationReadOnlyList.GetAllEnabledPresentations();
                GetNextPresentation();
            }
        }

        private void ChangeSlide()
        {
            if (currentPresentation.PresentationTypeName == "Slideshow")
            {
                GenerateImage();
            }
            else if (currentPresentation.PresentationTypeName == "Video")
            {
                ShowVideo();
            }
        }

        private void ShowVideo()
        {
            string videoFile = slidePath + currentSlide.Location;
            vidSlide.Source = new Uri(videoFile, UriKind.Absolute);
            timer.Stop();
            vidSlide.Play();

        }

        // stop slideshow when we show a video
        private void vidSlide_MediaOpened(object sender, RoutedEventArgs e)
        {

            Storyboard sb = (Storyboard)this.Resources["showVideoSlide"];
            sb.Begin(grdImages);
        }

        // start up slideshow timer when we're done showing video again
        private void vidSlide_MediaEnded(object sender, RoutedEventArgs e)
        {
            Storyboard sb = (Storyboard)this.Resources["hideVideoSlide"];
            sb.Begin(grdImages);

            vidSlide.Close();
            timer_Tick(this, new EventArgs());
            timer.Start();
            
        }


        private void GenerateImage()
        {
            try
            {

                string templateFile = slidePath + "template.html";
                string slideFile = slidePath + currentSlide.Location;

                if (!File.Exists(templateFile) || !File.Exists(slideFile))
                {
                    return;
                }

                // get slide and template contents to merge them
                string templateContents = "",
                    slideContents = "";
                using (StreamReader sr = new StreamReader(templateFile))
                {
                    templateContents = sr.ReadToEnd();
                }
                using (StreamReader sr = new StreamReader(slideFile))
                {
                    slideContents = sr.ReadToEnd();
                }

                // write the temp slide
                using (StreamWriter sw = new StreamWriter(tempFile, false))
                {
                    sw.Write(string.Format(templateContents, slideContents));
                }

                
                imgGen.GenerateImage();
            }
            catch (Exception ex)
            { 
                MessageBox.Show("Error generating image: " + ex.ToString());
            }
        }

        void imgGen_GenerationComplete(object sender, EventArgs e)
        {
            currSlideNum = currSlideNum % 2;

            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
                bi.CacheOption = BitmapCacheOption.OnLoad;
                bi.StreamSource = imgGen.ImageStream;
            bi.EndInit();

           Storyboard sb = null;
           if (currSlideNum == 0)
           {
               sb = (Storyboard)this.Resources["showSlide1"];
               imgSlide1.Source = null;
               imgSlide1.Source = bi;
           }
           else if (currSlideNum == 1)
           {
               sb = (Storyboard)this.Resources["showSlide2"];
               imgSlide2.Source = null;
               imgSlide2.Source = bi;
           }
           sb.Begin(grdImages);

           currSlideNum++;
        }

        public void Pause()
        {
            if (currentPresentation.PresentationTypeName == "Slideshow")
            {
                timer.Stop();
            }
            else if (currentPresentation.PresentationTypeName == "Video")
            {
                vidSlide.Pause();
            }

        }

        public void Resume()
        {
            if (currentPresentation.PresentationTypeName == "Slideshow")
            {
                timer.Start();
            }
            else if (currentPresentation.PresentationTypeName == "Video")
            {
                vidSlide.Play();
            }

        }

        private void vidSlide_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            Storyboard sb = (Storyboard)this.Resources["hideVideoSlide"];
            sb.Begin(grdImages);
            vidSlide.Close();

            timer.Start();
        }






    }
}
